package sqlfactory

import (
	"database/sql"
	"fmt"
	"reflect"
	"strconv"
	"strings"
	"time"
	"unsafe"

	"gitee.com/tomatomeatman/golang-repository/bricks3/function/data/stringutil"
	"gitee.com/tomatomeatman/golang-repository/bricks3/model/dbinfo"
	"gitee.com/tomatomeatman/golang-repository/bricks3/utils/gormutil"
	Log "github.com/cihub/seelog"
	"github.com/shopspring/decimal"
	"gorm.io/gorm"
)

// 操作类型常量
const (
	OpTypeCreate = "create"
	OpTypeUpdate = "update"
	OpTypeDelete = "delete"
)

// Operation 事务操作定义
type Operation struct {
	Type         string                   `json:"type"`         // 操作类型
	DBName       string                   `json:"dbName"`       // 数据库名
	TableName    string                   `json:"tableName"`    // 表名
	Conditions   []*dbinfo.ConditionGroup `json:"conditions"`   // 查询条件
	Data         interface{}              `json:"data"`         // 操作数据
	ExpectedRows int64                    `json:"expectedRows"` // 预期影响行数
}

// QueryOne 单条查询
func FindOneByWrapper(wrapper *dbinfo.QueryWrapper, dbName, tableName string) (bool, string, interface{}) {
	result := &dbinfo.QueryResult{Success: false}
	defer recoverPanic(result)

	tx := buildQuery(gormutil.GetGorm(dbName), wrapper, tableName)

	rows, err := tx.Rows()
	if err != nil {
		Log.Error("查询发生异常:", tx.Error.Error())
		return false, "查询失败: " + err.Error(), 5003
	}

	defer rows.Close()

	res := scanRows2mapI(rows, false)
	if res == nil {
		Log.Error("查询成功后进行数据转换时发生异常,:无法正确转换")
		return false, "查询发生异常", 5004
	}

	rowCount := len(res)
	if rowCount < 1 {
		return false, "没有数据", 1990 //没有数据
	}

	return true, "查询成功", removeNilFieldsFromMap(res[0])
}

// QueryMulti 按Wrapper查询多条记录
func FindListByWrapper(wrapper *dbinfo.QueryWrapper, dbName, tableName string) (bool, string, interface{}) {
	result := &dbinfo.QueryResult{Success: false}
	defer recoverPanic(result)

	db := gormutil.GetGorm(dbName)

	tx := buildQuery(db, wrapper, tableName)

	rows, err := tx.Rows()
	if err != nil {
		Log.Error("查询发生异常:", tx.Error.Error())
		return false, "查询失败: " + err.Error(), 5003
	}

	defer rows.Close()

	res := scanRows2mapI(rows, false)
	if res == nil {
		Log.Error("查询成功后进行数据转换时发生异常,:无法正确转换")
		return false, "查询发生异常", 5003
	}

	if len(res) < 1 {
		return false, "没有数据", 1990 //没有数据
	}

	return true, "查询成功", removeNilFieldsFromSlice(res)
}

// FindList 按Wrapper进行分页查询
func FindPageByWrapper(wrapper *dbinfo.QueryWrapper, dbName, tableName string, page, pageSize int) (bool, string, interface{}) {
	// 总数查询
	tx := buildQuery(gormutil.GetGorm(dbName), wrapper, tableName)
	var total int64
	if err := tx.Count(&total).Error; err != nil {
		Log.Error("获取总数发生异常:", tx.Error.Error())
		return false, "获取总数失败: " + tx.Error.Error(), 5002
	}

	if total < 1 {
		result := map[string]interface{}{
			"current":   page,
			"size":      pageSize,
			"countRow":  0,
			"countPage": total,
			"record":    []map[string]interface{}{},
		}

		return true, "查询成功,但没有数据", result
	}

	// 分页查询
	if page > 0 && pageSize > 0 {
		tx = tx.Offset((page - 1) * pageSize).Limit(pageSize)
	}

	rows, err := tx.Rows()
	if err != nil {
		Log.Error("查询发生异常:", tx.Error.Error())
		return false, "查询失败: " + err.Error(), 5003
	}

	defer rows.Close()

	res := scanRows2mapI(rows, false)
	if res == nil {
		Log.Error("查询成功后进行数据转换时发生异常,:无法正确转换")
		return false, "查询发生异常", 5003
	}

	rowCount := len(res)
	if rowCount < 1 {
		return false, "没有数据", 1990 //没有数据
	}

	iTemp := (total / int64(pageSize))
	if (total % int64(pageSize)) != 0 {
		iTemp = iTemp + 1
	}

	result := map[string]interface{}{
		"current":   page,
		"size":      pageSize,
		"countRow":  total,
		"countPage": iTemp,
		"record":    removeNilFieldsFromSlice(res),
	}

	return true, "查询成功", result
}

/**
 * 删除nil字段
 */
func removeNilFieldsFromSlice(s []map[string]interface{}) []map[string]interface{} {
	var result []map[string]interface{}
	for _, item := range s {
		result = append(result, removeNilFieldsFromMap(item))
	}
	return result
}

/**
 * 删除nil字段
 */
func removeNilFieldsFromMap(m map[string]interface{}) map[string]interface{} {
	result := make(map[string]interface{})
	for k, v := range m {
		if v != nil {
			result[k] = v
		}
	}
	return result
}

// 按原生sql查询数据,并按指定格式返回数据
func Find(dbName string, result interface{}, sql string, params ...interface{}) (bool, string, interface{}) {
	vParams := []interface{}{}
	if len(params) > 1 {
		vParams = append(vParams, params...)
	} else if len(params) == 1 {
		if v, ok := params[0].(map[string]interface{}); ok {
			if len(v) > 0 {
				vParams = append(vParams, params...)
			}
		} else if v, ok := params[0].([]interface{}); ok {
			if len(v) > 0 {
				vParams = append(vParams, v...)
			}
		} else if params[0] != nil {
			vParams = append(vParams, params[0])
		}
	}

	dbResult := gormutil.GetGorm(dbName).Raw(sql, vParams...).Find(result)

	if dbResult.Error != nil {
		Log.Error("查询发生异常:", dbResult.Error)
		return false, "查询数据发生异常", 1002
	}

	if result == nil {
		return false, "没有数据", 1990 //没有数据
	}

	return true, "查询成功", result
}

// 查询单个字段
func FindColumn(dbName, sql string, params ...interface{}) (bool, string, interface{}) {
	vParams := []interface{}{}
	if len(params) > 1 {
		vParams = append(vParams, params...)
	} else if len(params) == 1 {
		if v, ok := params[0].(map[string]interface{}); ok {
			if len(v) > 0 {
				vParams = append(vParams, params...)
			}
		} else if v, ok := params[0].([]interface{}); ok {
			if len(v) > 0 {
				vParams = append(vParams, v...)
			}
		} else if params[0] != nil {
			vParams = append(vParams, params[0])
		}
	}

	var data interface{}
	dbResult := gormutil.GetGorm(dbName).Raw(sql, vParams...).Find(&data)
	if dbResult.Error != nil {
		Log.Error("查询发生异常:", dbResult.Error)
		return false, "查询数据发生异常", 1002
	}

	if data == nil {
		return false, "没有数据", 1990 //没有数据
	}

	return true, "查询成功", data
}

// FindOne 查询单条数据
func FindOne(dbName, sql string, params ...interface{}) (bool, string, interface{}) {
	vParams := []interface{}{}
	if len(params) > 1 {
		vParams = append(vParams, params...)
	} else if len(params) == 1 {
		if v, ok := params[0].(map[string]interface{}); ok {
			if len(v) > 0 {
				vParams = append(vParams, params...)
			}
		} else if v, ok := params[0].([]interface{}); ok {
			if len(v) > 0 {
				vParams = append(vParams, v...)
			}
		} else if params[0] != nil {
			vParams = append(vParams, params[0])
		}
	}

	var data map[string]interface{}
	dbResult := gormutil.GetGorm(dbName).Raw(sql, vParams...).Find(&data)
	if dbResult.Error != nil {
		Log.Error("查询发生异常:", dbResult.Error)
		return false, "查询数据发生异常", 1002
	}

	if len(data) < 1 {
		return false, "没有数据", 1990 //没有数据
	}

	return true, "查询成功", data
}

// 查询列表
func FindList(dbName, sql string, params ...interface{}) (bool, string, interface{}) {
	vParams := []interface{}{}
	if len(params) > 1 {
		vParams = append(vParams, params...)
	} else if len(params) == 1 {
		if v, ok := params[0].(map[string]interface{}); ok {
			if len(v) > 0 {
				vParams = append(vParams, params...)
			}
		} else if v, ok := params[0].([]interface{}); ok {
			if len(v) > 0 {
				vParams = append(vParams, v...)
			}
		} else if params[0] != nil {
			vParams = append(vParams, params[0])
		}
	}

	var data []map[string]interface{}
	dbResult := gormutil.GetGorm(dbName).Raw(sql, vParams...).Find(&data)
	if dbResult.Error != nil {
		Log.Error("查询发生异常:", dbResult.Error)
		return false, "查询数据发生异常", 1002
	}

	if len(data) < 1 {
		return false, "没有数据", 1990 //没有数据
	}

	return true, "查询成功", data
}

// ExecSql
func ExecSql(dbName, sql string, params ...interface{}) (bool, string, interface{}) {
	vParams := []interface{}{}
	if len(params) > 1 {
		vParams = append(vParams, params...)
	} else if len(params) == 1 {
		if v, ok := params[0].(map[string]interface{}); ok {
			if len(v) > 0 {
				vParams = append(vParams, params...)
			}
		} else if params[0] != nil {
			vParams = append(vParams, params[0])
		}
	}

	dbResult := gormutil.GetGorm(dbName).Exec(sql, vParams...)
	if dbResult.Error != nil {
		Log.Error("执行更新发生异常:", dbResult.Error)
		return false, "更新数据发生异常:" + dbResult.Error.Error(), 7001
	}

	return true, "执行成功,影响数为", dbResult.RowsAffected
}

// 指定id数据是否存在,存在返回true
func HasById(dbName, tableName, idName string, idValue interface{}, delSignName string) (bool, string, interface{}) {
	txt := "SELECT COUNT(1) AS iCount FROM " + tableName + " WHERE " + idName + " = ?"
	if delSignName != "" {
		txt += " AND " + delSignName + " = 0"
	}

	var iCount int
	dbResult := gormutil.GetGorm(dbName).Raw(txt, idValue).Find(&iCount)
	if dbResult.Error != nil {
		Log.Error("查询发生异常:", dbResult.Error)
		return false, "查询数据发生异常", 1002
	}

	if iCount == 0 {
		return false, "没有数据", 1990 //没有数据
	}

	return true, "数据存在", iCount
}

// 查询指定id数据
func FindById(dbName, tableName, idName string, idValue interface{}, delSignName string) (bool, string, interface{}) {
	txt := "SELECT * FROM " + tableName + " WHERE " + idName + " = ?"
	if delSignName != "" {
		txt += " AND " + delSignName + " = 0"
	}

	var data map[string]interface{}
	dbResult := gormutil.GetGorm(dbName).Raw(txt, idValue).Find(&data)
	if dbResult.Error != nil {
		Log.Error("查询发生异常:", dbResult.Error)
		return false, "查询数据发生异常", 1002
	}

	if len(data) < 1 {
		return false, "没有数据", 1990 //没有数据
	}

	return true, "查询成功", data
}

// Create 创建记录
func Add(dbName, tableName string, data map[string]interface{}, keyName string, autoKey bool) (bool, string, interface{}) {
	tx := gormutil.GetGorm(dbName).Table(tableName).Create(data)
	if tx.Error != nil {
		Log.Error("执行新增发生异常:", tx.Error.Error())
		return false, "新增失败: " + tx.Error.Error(), 1001
	}

	if v, ok := data["@id"]; ok { //自增组件会返回@id
		data[keyName] = v
		delete(data, "@id")
	}

	return true, "新增成功", data
}

// // Create 创建记录//参考
// func InsertData(dbName, tableName string, data map[string]interface{}, keyName string, autoKey bool) (bool, string, interface{}) {
// 	tx := gormutil.GetGorm(dbName).Table(tableName).Create(data)
// 	if tx.Error != nil {
// 		Log.Error("执行新增发生异常:", tx.Error.Error())
// 		return false, "新增失败: " + tx.Error.Error(), 1001
// 	}

// 	if autoKey {
// 		var lastID int64
// 		tx := gormutil.GetGorm(dbName).Raw("SELECT LAST_INSERT_ID()").Scan(&lastID)
// 		if tx.Error != nil {
// 			Log.Error("取自增id发生异常:", tx.Error.Error())
// 			return false, "新增成功,但取自增id发生异常: " + tx.Error.Error(), 1002
// 		}

// 		data[keyName] = lastID
// 	}

// 	return true, "新增成功", data
// }

// // Create 创建记录//参考
// func InsertData(dbName, tableName string, data map[string]interface{}, autoKey bool) (bool, string, interface{}) {
// result := &dbinfo.QueryResult{Success: false}
// defer recoverPanic(result)

// // 1. 构建字段信息
// fields := make([]reflect.StructField, 0, len(data))
// values := make(map[string]interface{})

// for k, v := range data {
// 	typ := reflect.TypeOf(v)
// 	if typ == nil { // 处理 nil 值的情况
// 		typ = reflect.TypeOf("")
// 	}

// 	// 判断是否为主键字段（假设主键为 id）
// 	tag := ""
// 	if autoKey {
// 		tag = `gorm:"primaryKey;autoIncrement"`
// 	}

// 	fields = append(fields, reflect.StructField{
// 		Name: ToPublicFieldName(k), // 字段名转为大写开头
// 		Type: typ,
// 		Tag:  reflect.StructTag(tag),
// 	})
// 	values[k] = v
// }

// // 2. 动态创建结构体类型
// structType := reflect.StructOf(fields)

// // 3. 创建结构体实例
// instance := reflect.New(structType).Elem()

// // 4. 给结构体字段赋值
// for k, v := range values {
// 	fieldName := ToPublicFieldName(k)
// 	f := instance.FieldByName(fieldName)
// 	if f.IsValid() && f.CanSet() {
// 		f.Set(reflect.ValueOf(v))
// 	}
// }

// fmt.Println(instance)

// // 5. 插入数据库
// tx := gormutil.GetGorm(dbName).Table(tableName).Create(instance.Addr().Interface())
// if tx.Error != nil {
// 	Log.Error("执行新增发生异常:", tx.Error.Error())
// 	return false, "新增失败: " + tx.Error.Error(), 5002
// }

// return true, "新增成功", instance
// }

// // 将字段名转换为导出字段名（首字母大写）
// func ToPublicFieldName(name string) string {
// 	runes := []rune(name)
// 	if len(runes) == 0 {
// 		return ""
// 	}
// 	return string(append([]rune{unicode.ToUpper(runes[0])}, runes[1:]...))
// }

// func getAutoIncrementID(db *gorm.DB, tableName string, data map[string]interface{}) (interface{}, bool) {
// 	var id interface{}

// 	// 如果数据库支持 LAST_INSERT_ID()，可以使用 Raw 查询获取最后插入的 ID
// 	row := db.Raw("SELECT LAST_INSERT_ID()").Row()
// 	if err := row.Scan(&id); err == nil {
// 		return id, true
// 	}

// 	// 如果 LAST_INSERT_ID 不可用，可尝试使用 GORM Last 方法（需主键字段为 "id"）
// 	if val, ok := data["id"]; ok && val == nil {
// 		// 主键字段存在但为空，说明是自增字段
// 		if err := db.Table(tableName).Last(&data).Error; err == nil {
// 			return data["id"], true
// 		}
// 	}

// 	return nil, false
// }

//--------------------------------------------------//

// Edit 更新记录
func Edit(wrapper *dbinfo.QueryWrapper, dbName, tableName string, data map[string]interface{}) (bool, string, interface{}) {
	db := gormutil.GetGorm(dbName)

	tx := buildQuery(db, wrapper, tableName).Updates(data)
	if tx.Error != nil {
		Log.Error("执行更新发生异常:", tx.Error.Error())
		return false, "更新失败: " + tx.Error.Error(), 5002
	}

	// 处理影响行数为0的情况
	if tx.RowsAffected > 0 {
		return true, "更新成功", tx.RowsAffected
	}

	return false, "更新失败,影响数为0", 5002
}

// Delete 删除记录
// 返回：QueryResult 包含操作结果
func Del(wrapper *dbinfo.QueryWrapper, dbName, tableName string) (bool, string, interface{}) {
	db := gormutil.GetGorm(dbName) // 确保数据库连接已初始化

	// 构建查询条件
	tx := buildQuery(db, wrapper, tableName).Delete(nil)

	if tx.Error != nil {
		Log.Error("执行删除发生异常:", tx.Error.Error())
		return false, "删除失败: " + tx.Error.Error(), 5002
	}

	// 处理影响行数为0的情况
	if tx.RowsAffected > 0 {
		return true, "删除成功", tx.RowsAffected
	}

	return false, "删除失败,影响数为0", 5002
}

// CountData 统计数量
func CountData(dbName, tableName string, wrapper *dbinfo.QueryWrapper) (bool, string, interface{}) {
	db := gormutil.GetGorm(dbName)

	var count int64

	query := buildQuery(db, wrapper, tableName)

	if err := query.Count(&count).Error; err != nil {
		return false, "查询失败: " + err.Error(), 5002
	}

	return true, "查询成功", count
}

// MaxValue 查询最大值
func MaxValue(dbName, tableName, field string, group []*dbinfo.ConditionGroup) (bool, string, interface{}) {
	db := gormutil.GetGorm(dbName)

	query := db.Table(tableName)
	query = buildConditions(query, group)

	var max interface{}
	if err := query.Select(fmt.Sprintf("MAX(%s) as max", field)).Scan(&max).Error; err != nil {
		return false, "查询失败: " + err.Error(), 5002
	}

	return true, "查询成功", max
}

// MinValue 查询最小值
func MinValue(dbName, tableName, field string, group []*dbinfo.ConditionGroup) (bool, string, interface{}) {
	db := gormutil.GetGorm(dbName)

	query := db.Table(tableName)
	query = buildConditions(query, group)

	var min interface{}
	if err := query.Select(fmt.Sprintf("MIN(%s) as min", field)).Scan(&min).Error; err != nil {
		return false, "查询失败: " + err.Error(), 5002
	}

	return true, "查询成功", min
}

// 分组查询
func GroupValue(wrapper *dbinfo.QueryWrapper, dbName, tableName string) (bool, string, interface{}) {
	tx := buildQuery(gormutil.GetGorm(dbName), wrapper, tableName)

	if len(wrapper.GroupFields) > 0 {
		temp := ""
		for _, field := range wrapper.GroupFields {
			if temp != "" {
				temp += ", "
			}
			temp += field
		}

		tx = tx.Group(temp)
	} else {
		temp := ""
		for _, field := range wrapper.Fields {
			if temp != "" {
				temp += ", "
			}
			temp += field
		}

		tx = tx.Group(temp)
	}

	if len(wrapper.Havings) > 0 {
		column := ""
		args := []interface{}{}
		for _, v := range wrapper.Havings {
			if column != "" {
				column += " AND "
			}
			column += v.Field + " " + v.Operator + " ?"
			args = append(args, v.Value)
		}

		tx = tx.Having(column, args...)
	}

	rows, err := tx.Rows()
	if err != nil {
		Log.Error("查询发生异常:", tx.Error.Error())
		return false, "查询失败: " + err.Error(), 5003
	}

	defer rows.Close()

	res := scanRows2mapI(rows, false)
	if res == nil {
		Log.Error("查询成功后进行数据转换时发生异常,:无法正确转换")
		return false, "查询发生异常", 5003
	}

	if len(res) < 1 {
		return false, "没有数据", 1990 //没有数据
	}

	return true, "执行成功", removeNilFieldsFromSlice(res)
}

// Transaction 执行事务
func Transaction(dbName string, operations []*Operation) (bool, string, interface{}) {
	db := gormutil.GetGorm(dbName)

	tx := db.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()

	totalAffected := int64(0)
	for _, op := range operations {
		affected, err := processOperation(tx, op)
		if err != nil {
			tx.Rollback()
			return false, "事务执行失败: " + err.Error(), 5002
		}

		if op.ExpectedRows > 0 && affected != op.ExpectedRows {
			tx.Rollback()
			return false, fmt.Sprintf("影响行数不符预期 (期望 %d, 实际 %d)", op.ExpectedRows, affected), 5003
		}

		totalAffected += affected
	}

	if err := tx.Commit().Error; err != nil {
		return false, "事务提交失败: " + err.Error(), 5004
	}

	return true, "执行成功", withAffectedRows(totalAffected)
}

// // 内部实现方法
// func buildTableName(dbName, tableName string) string {
// 	if dbName == "" {
// 		return tableName
// 	}

// 	dbName = getDbVariables(dbName)

// 	return fmt.Sprintf("%s%s", dbName, tableName)
// }

func buildQuery(db *gorm.DB, wrapper *dbinfo.QueryWrapper, tableName string) *gorm.DB {
	tx := db.Table(tableName)
	tx = buildConditions(tx, wrapper.ConditionGroup)

	if len(wrapper.Fields) > 0 {
		tx = tx.Select(wrapper.Fields)
	}

	for _, order := range wrapper.Orders {
		tx = tx.Order(fmt.Sprintf("%s %s", order.Field, order.Order))
	}

	return tx
}

// 构建查询条件
func buildConditions(tx *gorm.DB, group []*dbinfo.ConditionGroup) *gorm.DB {
	if len(group) == 0 {
		return tx
	}

	for _, g := range group {
		if len(g.Conditions) == 0 && len(g.Children) == 0 {
			continue
		}

		// 处理当前条件组
		for _, cond := range g.Conditions {
			tx = applyCondition(tx, cond, g.Type == dbinfo.CondTypeOr)
		}

		if len(g.Children) == 0 {
			continue
		}

		// 处理嵌套条件
		switch g.Type {
		case dbinfo.CondTypeAnd:
			tx = tx.Where(buildConditions(tx, g.Children))
		case dbinfo.CondTypeOr:
			tx = tx.Or(buildConditions(tx, g.Children))
		}
	}

	return tx
}

func applyCondition(tx *gorm.DB, cond *dbinfo.QueryCondition, isOr bool) *gorm.DB {
	switch strings.ToLower(cond.Operator) {
	case "=", ">", "<", ">=", "<=":
		if isOr {
			return tx.Or(fmt.Sprintf("%s %s ?", cond.Field, cond.Operator), cond.Value)
		}
		return tx.Where(fmt.Sprintf("%s %s ?", cond.Field, cond.Operator), cond.Value)
	case "like":
		if isOr {
			return tx.Or(fmt.Sprintf("%s LIKE ?", cond.Field), cond.Value)
		}
		return tx.Where(fmt.Sprintf("%s LIKE ?", cond.Field), cond.Value)
	case "in":
		if isOr {
			return tx.Or(fmt.Sprintf("%s IN (?)", cond.Field), cond.Value)
		}
		return tx.Where(fmt.Sprintf("%s IN (?)", cond.Field), cond.Value)
	case "not in":
		if isOr {
			return tx.Or(fmt.Sprintf("%s NOT IN (?)", cond.Field), cond.Value)
		}
		return tx.Where(fmt.Sprintf("%s NOT IN (?)", cond.Field), cond.Value)
	case "between":
		if values, ok := cond.Value.([]interface{}); ok && len(values) == 2 {
			if isOr {
				return tx.Or(fmt.Sprintf("%s BETWEEN ? AND ?", cond.Field), values[0], values[1])
			}
			return tx.Where(fmt.Sprintf("%s BETWEEN ? AND ?", cond.Field), values[0], values[1])
		}
	default:
		Log.Error("不支持的查询操作符: ", cond.Operator)
	}
	return tx
}

func processOperation(tx *gorm.DB, op *Operation) (int64, error) {
	table := op.TableName
	switch op.Type {
	case OpTypeCreate:
		result := tx.Table(table).Create(op.Data)
		return result.RowsAffected, result.Error
	case OpTypeUpdate:
		tx = buildConditions(tx.Table(table), op.Conditions)
		result := tx.Updates(op.Data)
		return result.RowsAffected, result.Error
	case OpTypeDelete:
		tx = buildConditions(tx.Table(table), op.Conditions)
		result := tx.Delete(nil)
		return result.RowsAffected, result.Error
	default:
		return 0, fmt.Errorf("不支持的操作类型: %s", op.Type)
	}
}

// 辅助函数
func recoverPanic(result *dbinfo.QueryResult) {
	if r := recover(); r != nil {
		result.Error = fmt.Sprintf("运行时异常: %v", r)
		Log.Error(result.Error)
	}
}

// func handleQueryError(result *dbinfo.QueryResult, err error) (bool, string, interface{}) {
// 	if errors.Is(err, gorm.ErrRecordNotFound) {
// 		result.Success = true
// 		result.Message = "未找到匹配记录"
// 		return result
// 	}
// 	result.Error = "查询失败: " + err.Error()
// 	return result
// }

// func successResult(result *dbinfo.QueryResult, data interface{}, opts ...func(*dbinfo.QueryResult)) (bool, string, interface{}) {
// 	result.Success = true
// 	result.Data = data
// 	for _, opt := range opts {
// 		opt(result)
// 	}

// 	return result
// }

func withAffectedRows(rows int64) func(*dbinfo.QueryResult) {
	return func(r *dbinfo.QueryResult) {
		if r.Extra == nil {
			r.Extra = make(map[string]interface{})
		}
		r.Extra["affectedRows"] = rows
	}
}

// 将查询结果转换成map数组,常用于原生sql查询
func scanRows2mapI(rows *sql.Rows, toCamel bool) []map[string]interface{} {
	defer rows.Close()

	columns, err := rows.Columns()
	if err != nil {
		return nil
	}

	values := make([]interface{}, len(columns))
	valuePtrs := make([]interface{}, len(columns))
	camelMap := make(map[string]string, len(columns))
	for i := range columns {
		valuePtrs[i] = &values[i]
		if toCamel {
			columns[i] = stringutil.ToCamel(columns[i]) //转换驼峰
		} else {
			camelMap[columns[i]] = columns[i]
		}
	}

	colNames := make(map[string]string)
	temp, _ := rows.ColumnTypes() // 列信息
	for _, colType := range temp {
		colNames[colType.Name()] = strings.ToUpper(colType.DatabaseTypeName()) // 跟据数据库参数类型，创建默认值 和类型
	}

	maps := []map[string]interface{}{} //就算没数据也不会返回nil
	for rows.Next() {
		err := rows.Scan(valuePtrs...)
		if err != nil {
			return nil
		}

		m := make(map[string]interface{})
		for i, col := range columns {
			m[camelMap[col]] = dbValueCorrect(colNames[col], values[i])
		}

		maps = append(maps, m)
	}

	return maps
}

/**
 * 将查询结果修正成符合字段类型的数据
 * 比如DECIMAL类型的值如果不进行修正返回会是字符串
 * @param colType 数据库字段类型
 * @param val 数据库字段值
 * @return 修正后的数据
 */
func dbValueCorrect(colType string, val interface{}) interface{} {
	if val == nil {
		return nil
	}

	colType = strings.ToUpper(colType)
	switch colType {
	case "INT":
		value := toInt(val, -99999)
		if value != -99999 {
			return value
		}
	case "NUMERIC":
		value := toInt(val, -99999)
		if value != -99999 {
			return value
		}
	case "TINYINT":
		value := toInt(val, -99999)
		if value != -99999 {
			return value
		}
	case "BIGINT":
		value := toInt(val, -99999)
		if value != -99999 {
			return value
		}
	case "FLOAT":
		value := toFloat(val, 64, -99999999.99999999)
		if value != -99999999.99999999 {
			return value
		}
	case "DOUBLE":
		value := toFloat(val, 64, -99999999.99999999)
		if value != -99999999.99999999 {
			return value
		}
	case "DECIMAL":
		switch reflect.TypeOf(val).Elem().Name() {
		case "Decimal":
			return val.(*decimal.Decimal)
		case "uint8":
			temp, _ := decimal.NewFromString(toStr(val))
			return temp
		case "string":
			temp, _ := decimal.NewFromString(val.(string))
			return temp
		default:
			return val
		}
	case "DATETIME":
		return val.(time.Time).Format("2006-01-02 15:04:05")
	case "DATE":
		return val.(time.Time).Format("2006-01-02 15:04:05")
	case "TIME":
		return val.(time.Time).Format("2006-01-02 15:04:05")
	case "TIMESTAMP":
		return toInt(val, -99999)
	default:
		b, ok := val.([]byte)
		if ok {
			return string(b)
		}

		return val
	}

	return val //都不在范围内,不转换
}

// Byte转Str
func byte2Str(b []byte) string {
	return *(*string)(unsafe.Pointer(&b))
}

// 转换字符串
func toStr(data interface{}) string {
	switch obj := data.(type) {
	case []uint8:
		return byte2Str(obj)
	default:
		return fmt.Sprintf("%v", data)
	}
}

// 对象(字符串)转整型
func toInt(data interface{}, iDefault int) int {
	var str string
	switch obj := data.(type) {
	case []uint8:
		str = byte2Str(obj)
	default:
		str = fmt.Sprintf("%v", obj)
	}

	if str == "" { //字符串不能判断nil
		return iDefault
	}

	result, err := strconv.ParseInt(str, 10, 64)
	if err != nil {
		return iDefault
	}

	return int(result)
}

// 对象(字符串)转64整型
func toFloat(data interface{}, bitSize int, iDefault float64) float64 {
	var str string
	switch obj := data.(type) {
	case []uint8:
		str = byte2Str(obj)
	default:
		str = fmt.Sprintf("%v", obj)
	}

	if str == "" { //字符串不能判断nil
		return iDefault
	}

	result, err := strconv.ParseFloat(str, bitSize)
	if err != nil {
		return iDefault
	}

	return result
}

// 查询表字段信息
func FindField(dbName, tableName string) (bool, string, interface{}) {
	text := findFieldSql(gormutil.GetDbType(dbName))

	var data []*dbinfo.Field
	tx := gormutil.GetGorm(dbName).Raw(text, dbName, tableName).Scan(&data)
	if tx.Error != nil {
		Log.Error("查询发生异常:", tx.Error.Error())
		return false, "查询失败: " + tx.Error.Error(), 5002
	}

	return true, "查询成功", data
}

// 查询表字段名信息
func FindFieldName(dbName, tableName string) (bool, string, interface{}) {
	text := findFieldNameSql(gormutil.GetDbType(dbName))
	var data []string
	tx := gormutil.GetGorm(dbName).Raw(text, dbName, tableName).Scan(&data)
	if tx.Error != nil {
		Log.Error("查询发生异常:", tx.Error.Error())
		return false, "查询失败: " + tx.Error.Error(), 5002
	}

	return true, "查询成功", data
}

/**
 * 取指定节点下的子节点编号
 * @param dbName 数据库名
 * @param tableName 表名
 * @param idName 主键名
 * @param pidName 父节点字段名
 * @param pidValue 父节点值
 * @return
 */
func NewChildId(dbName, tableName, idName, pidName, pidValue string) (bool, string, interface{}) {
	txt := NewChildIdSql(gormutil.GetDbType(dbName), tableName, idName, pidName, pidValue)

	newId := ""
	dbResult := gormutil.GetGorm(dbName).Raw(txt, sql.Named(pidName, pidValue)).Find(&newId)
	if dbResult.Error != nil {
		Log.Error("查询发生异常:", dbResult.Error)
		return false, "查询数据发生异常:" + dbResult.Error.Error(), 1001
	}

	return true, "获取子节点编号成功", newId
}

// 分析并获取实体
func AnalysisEntity(dbName string, tableNameIf interface{}) (bool, string, interface{}) {
	if tableNameIf == nil {
		return false, "tableName参数为空", 9001
	}

	tableName := strings.TrimSpace(fmt.Sprintf("%v", tableNameIf))

	if tableName == "" {
		return false, "tableName参数为空", 9002
	}

	bl, msg, data := FindTableInfo(dbName, tableName)
	if !bl {
		return bl, msg, data
	}

	entity := data.(*dbinfo.TableInfo)

	return bl, msg, entity
}
